package library.admin.controller;

import library.admin.domain.dto.PageDTO;
import library.admin.domain.po.Book;
import library.admin.domain.query.BookPageQuery;
import library.admin.domain.request.AddBookCopiesRequest;
import library.admin.domain.request.UpdateBookRequest;
import library.admin.domain.vo.BookBorrowedOverviewVO;
import library.admin.domain.vo.BookVO;
import library.admin.domain.request.SaveBookRequest;
import library.admin.response.ResponseResult;
import library.admin.service.IBooksService;
import library.admin.service.IFileService;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import library.admin.config.FileUploadConfig;

/**
 * 图书相关接口
 *
 * 
 *
 */
@RestController
@RequestMapping("/books")
@Api(tags = "图书相关接口")
@RequiredArgsConstructor
@Slf4j
public class BooksController {
    private final IBooksService booksService;
    private final IFileService fileService;
    private final FileUploadConfig fileUploadConfig;

    @GetMapping("page")
    @ApiOperation("分页获取图书概览信息")
    public ResponseResult<PageDTO<BookBorrowedOverviewVO>> booksOverviewByPage(BookPageQuery pageQuery) {
        PageDTO<BookBorrowedOverviewVO> pageDTO = booksService.booksOverviewByPage(pageQuery);
        return ResponseResult.success(pageDTO);
    }

    @PostMapping
    @ApiOperation("添加图书")
    public ResponseResult<Long> saveBook(@RequestBody SaveBookRequest saveBookRequest) {
        try {
            return ResponseResult.success(booksService.save(saveBookRequest));
        } catch (IllegalArgumentException iae) {
            return ResponseResult.fail(iae.getMessage());
        } catch (RuntimeException re) {
            log.error(re.getMessage());
            return ResponseResult.fail("后端异常，请联系管理人员！");
        }
    }

    @GetMapping("{id}")
    @ApiOperation("通过图书编号获取图书详细信息")
    public ResponseResult<BookVO> queryBookById(@PathVariable Long id) {
        try {
            return ResponseResult.success(booksService.queryBookDetails(id));
        } catch (IllegalArgumentException iae) {
            return ResponseResult.fail(null, iae.getMessage());
        }
    }

    @PutMapping
    @ApiOperation("修改图书")
    public ResponseResult<Book> updateBook(@RequestBody UpdateBookRequest request) {
        try {
            return ResponseResult.success(booksService.updateBook(request));
        } catch (IllegalArgumentException iae) {
            return ResponseResult.fail(iae.getMessage());
        } catch (RuntimeException re) {
            log.error(re.getMessage());
            return ResponseResult.fail("后端异常，请联系管理人员！");
        }
    }

    @PostMapping("copies")
    @ApiOperation("添加图书复本")
    public ResponseResult<? extends Serializable> addBookCopies(@RequestBody  AddBookCopiesRequest request) {
        try {
            booksService.addBookCopies(request);
            return ResponseResult.success();
        } catch (IllegalArgumentException iae) {
            return ResponseResult.fail(iae.getMessage());
        } catch (RuntimeException re) {
            log.error(re.getMessage());
            return ResponseResult.fail("后端异常，请联系管理人员！");
        }
    }

    @DeleteMapping("copies")
    @ApiOperation("下架图书复本")
    public ResponseResult<? extends Serializable> removeBookCopies(@RequestParam("copiesIds")List<Long> copiesIds) {
        try {
            booksService.removeBookCopies(copiesIds);
            return ResponseResult.success();
        } catch (IllegalArgumentException iae) {
            return ResponseResult.fail(iae.getMessage());
        } catch (RuntimeException re) {
            log.error(re.getMessage());
            return ResponseResult.fail("后端异常，请联系管理人员！");
        }
    }

    @DeleteMapping()
    @ApiOperation("下架图书")
    public ResponseResult<? extends Serializable> removeBooks(@RequestParam("bookIds")List<Long> bookIds) {
        try {
            booksService.removeBooks(bookIds);
            return ResponseResult.success();
        } catch (IllegalArgumentException iae) {
            return ResponseResult.fail(iae.getMessage());
        } catch (RuntimeException re) {
            log.error(re.getMessage());
            return ResponseResult.fail("后端异常，请联系管理人员！");
        }
    }
    
    @PostMapping("upload/cover")
    @ApiOperation("上传图书封面")
    @ApiImplicitParam(name = "file", value = "图书封面文件", required = true, dataType = "file")
    public ResponseResult<String> uploadBookCover(@RequestParam("file") MultipartFile file) {
        try {
            String coverUrl = fileService.uploadBookCover(file);
            return ResponseResult.success(coverUrl);
        } catch (IllegalArgumentException iae) {
            return ResponseResult.fail(iae.getMessage());
        } catch (IOException ioe) {
            log.error("文件上传失败", ioe);
            return ResponseResult.fail("文件上传失败：" + ioe.getMessage());
        } catch (RuntimeException re) {
            log.error("封面上传发生异常", re);
            return ResponseResult.fail("后端异常，请联系管理人员！");
        }
    }
    
    @GetMapping("download/cover")
    @ApiOperation("下载图书封面")
    public ResponseEntity<Resource> downloadBookCover(@RequestParam("coverUrl") String coverUrl) {
        try {
            if (StrUtil.isBlank(coverUrl) || !coverUrl.startsWith("/uploads/")) {
                log.warn("无效的封面URL格式: {}", coverUrl);
                return ResponseEntity.notFound().build();
            }
            
            // 从URL中提取文件名
            String filename = coverUrl.substring(coverUrl.lastIndexOf("/") + 1);
            
            // 使用配置中的上传路径
            String filePath = Paths.get(fileUploadConfig.getUploadPath(), filename).toString();
            log.info("下载文件路径: {}", filePath);
            
            File file = new File(filePath);
            
            if (!file.exists()) {
                log.error("文件不存在: {}", filePath);
                return ResponseEntity.notFound().build();
            }
            
            Path path = Paths.get(filePath);
            Resource resource = new UrlResource(path.toUri());
            
            // 处理文件名编码问题
            String encodedFilename = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
            
            // 强制以附件形式下载，无论文件类型
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .header(HttpHeaders.CONTENT_DISPOSITION, 
                            "attachment; filename=\"" + encodedFilename + "\"")
                    .body(resource);
        } catch (MalformedURLException e) {
            log.error("封面下载发生异常: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("下载处理过程中发生未知异常: {}", e.getMessage(), e);
            return ResponseEntity.status(500).build();
        }
    }
}
